/*
 * 原版接口
 */
import * as server from "@minecraft/server";
/*
 * 蛋白石数据
 */
import * as data_format from "../data/format";
import * as data_entity from "../data/entity";
/*
 * 导出模块
 */
export { Vector, QueryFoothold, QueryEntityFoothold, Clamp, Random, NumberID }
/**
 * * 向量计算 工具类
 */
class Vector {
    /**
     * * 判断向量是否相同
     * 
     * @param {server.Vector3} start - 向量对象
     * 
     * @param {server.Vector3} done - 向量对象
     * 
     * @returns {boolean} - 判断向量是否相同
     */
    static equals(start: server.Vector3, done: server.Vector3): boolean {
        return start.x === done.x && start.y === done.y && start.z === done.z;
    };
    /**
     * * 拷贝向量
     * 
     * @param {server.Vector3} vector - 向量对象
     * 
     * @returns {server.Vector3} - 拷贝后的向量对象
     */
    static copy(vector: server.Vector3): server.Vector3 {
        return this.add(vector, this.CONSTANT_ZERO);
    };
    /**
     * * 向量相加
     * 
     * @param {server.Vector3} start - 向量对象
     * 
     * @param {server.Vector3} done - 向量对象
     * 
     * @returns {server.Vector3} - 计算后的向量对象
     */
    static add(start: server.Vector3, done: server.Vector3): server.Vector3 {
        return { x: start.x + done.x, y: start.y + done.y, z: start.z + done.z };
    };
    /**
     * * 向量相减
     * 
     * @param {server.Vector3} start - 向量对象
     * 
     * @param {server.Vector3} done - 向量对象
     * 
     * @returns {server.Vector3} - 计算后的向量对象
     */
    static subtract(start: server.Vector3, done: server.Vector3): server.Vector3 {
        return { x: start.x - done.x, y: start.y - done.y, z: start.z - done.z };
    };
    /**
     * * 向量缩放
     * 
     * @param {server.Vector3} vector - 向量对象
     * 
     * @param {number} scale - 缩放值
     * 
     * @returns {server.Vector3} - 计算后的向量对象
     */
    static scale(vector: server.Vector3, scale: number): server.Vector3 {
        return { x: vector.x * scale, y: vector.y * scale, z: vector.z * scale };
    };
    /**
     * * 向量点积值
     * 
     * @param {server.Vector3} start - 向量对象
     * 
     * @param {server.Vector3} done - 向量对象
     * 
     * @returns {number} - 两个向量的点积值
     */
    static dot(start: server.Vector3, done: server.Vector3): number {
        return start.x * done.x + start.y * done.y + start.z * done.z;
    };
    /**
     * * 向量叉积
     * 
     * @param {server.Vector3} start - 向量对象
     * 
     * @param {server.Vector3} done - 向量对象
     * 
     * @returns {server.Vector3} - 计算后的向量对象
     */
    static cross(start: server.Vector3, done: server.Vector3): server.Vector3 {
        return {
            x: start.y * done.z - start.z * done.y,
            y: start.z * done.x - start.x * done.z,
            z: start.x * done.y - start.y * done.x,
        };
    };
    /**
     * * 向量除法
     * 
     * @param {server.Vector3} vector - 向量对象
     * 
     * @param {number} divisor - 除数
     * 
     * @returns {server.Vector3} - 计算后的向量对象
     */
    static division(vector: server.Vector3, divisor: number): server.Vector3 {
        if (divisor === 0) return vector;
        return {
            x: vector.x / divisor,
            y: vector.y / divisor,
            z: vector.z / divisor
        };
    };
    /**
     * * 向量模长值
     * 
     * @param {server.Vector3} vector - 向量对象
     * 
     * @returns {number} - 两个向量的模长
     */
    static magnitude(vector: server.Vector3): number {
        return Math.sqrt(vector.x ** 2 + vector.y ** 2 + vector.z ** 2);
    };
    /**
     * * 向量距离值
     * 
     * @param {server.Vector3} start - 向量对象
     * 
     * @param {server.Vector3} done - 向量对象
     * 
     * @returns {number} - 两个向量间的距离
     */
    static distance(start: server.Vector3, done: server.Vector3): number {
        return this.magnitude(this.subtract(start, done));
    };
    /**
     * * 向量归一化
     * 
     * @param {server.Vector3} vector - 向量对象
     * 
     * @returns {server.Vector3} - 计算后的向量对象
     */
    static normalize(vector: server.Vector3): server.Vector3 {
        /**
         * * 计算向量模长
         */
        const mag = this.magnitude(vector);
        return { x: vector.x / mag, y: vector.y / mag, z: vector.z / mag };
    };
    /**
     * * 向量取整
     * 
     * @param {server.Vector3} vector - 向量对象
     * 
     * @param {number} decimals - 小数位数
     * 
     * @returns {server.Vector3} - 计算后的向量对象
     */
    static floor(vector: server.Vector3, decimals: number = 2): server.Vector3 {
        /**
         * * 获取乘数
         */
        const multiplier = Math.pow(10, decimals);
        return {
            x: Math.floor(vector.x * multiplier) / multiplier,
            y: Math.floor(vector.y * multiplier) / multiplier,
            z: Math.floor(vector.z * multiplier) / multiplier
        };
    };
    /**
     * * 向量转字符串
     * 
     * @param {server.Vector3 | server.Vector2} vector - 向量对象
     * 
     * @param {VECTOR_STRING_OPTIONS} options - 参数设置
     * 
     * @returns {string} - 向量字符串
     */
    static toString(vector: server.Vector3 | server.Vector2, options?: VECTOR_STRING_OPTIONS): string {
        /**
         * * 默认小数位数
         */
        const decimals = options?.decimals ?? 2;
        /**
         * * 向量 分隔字符串
         */
        const delimiter = options?.delimiter ?? ', ';
        /**
         * * 根据向量的类型, 获取不同的属性
         */
        const components = 'z' in vector
            ? [vector.x.toFixed(decimals), vector.y.toFixed(decimals), vector.z.toFixed(decimals)]
            : [vector.x.toFixed(decimals), vector.y.toFixed(decimals)];
        // 将向量组件连接成字符串
        return components.join(delimiter);
    };
    /**
     * * 向量范围限制
     * 
     * @param {server.Vector3} vector - 向量对象
     * 
     * @param {VECTOR_LIMITS} limits - 范围限制
     * 
     * @returns {server.Vector3} - 计算后的向量对象
     */
    static clamp(vector: server.Vector3, limits?: VECTOR_LIMITS): server.Vector3 {
        return {
            x: Clamp({ min: limits?.min?.x ?? Number.MIN_SAFE_INTEGER, max: limits?.max?.x ?? Number.MAX_SAFE_INTEGER }, vector.x),
            y: Clamp({ min: limits?.min?.y ?? Number.MIN_SAFE_INTEGER, max: limits?.max?.y ?? Number.MAX_SAFE_INTEGER }, vector.y),
            z: Clamp({ min: limits?.min?.z ?? Number.MIN_SAFE_INTEGER, max: limits?.max?.z ?? Number.MAX_SAFE_INTEGER }, vector.z),
        }
    };
    /**
     * * 向量 线性插值
     * 
     * @param {server.Vector3} start - 向量对象
     * 
     * @param {server.Vector3} done - 向量对象
     * 
     * @param {number} time - 时间系数
     * 
     * @returns {server.Vector3} - 计算后的向量对象
     */
    static lerp(start: server.Vector3, done: server.Vector3, time: number): server.Vector3 {
        return {
            x: start.x + (done.x - start.x) * time,
            y: start.y + (done.y - start.y) * time,
            z: start.z + (done.z - start.z) * time,
        }
    };
    /**
     * * 向量 球面线性插值
     * 
     * @param {server.Vector3} start - 向量对象
     * 
     * @param {server.Vector3} done - 向量对象
     * 
     * @param {number} time - 时间系数
     * 
     * @returns {server.Vector3} - 计算后的向量对象
     */
    static slerp(start: server.Vector3, done: server.Vector3, time: number): server.Vector3 {
        /**
         * * 计算两个向量点积
         */
        const angleCosine = this.dot(start, done);
        /**
         * * 确保角度余弦值在 [-1, 1] 区间内
         */
        const safeAngleCosine = Math.min(Math.max(angleCosine, -1), 1);
        /**
         * * 计算角度余弦值
         */
        const angleTheta = Math.acos(safeAngleCosine);
        /**
         * * 计算角度正弦值
         */
        const angleSin = Math.sin(angleTheta);
        /**
         * * 处理几乎平行的向量
         */
        if (Math.abs(angleSin) < Number.EPSILON) return start;
        /**
         * * 计算插值比例 对应 vectorA
         */
        const ratioA = Math.sin((1.0 - time) * angleTheta) / angleSin;
        /**
         * * 计算插值比例 对应 vectorB
         */
        const ratioB = Math.sin(time * angleTheta) / angleSin;
        // 根据插值比例对两个向量进行缩放, 然后相加得到插值结果
        return this.add(this.scale(start, ratioA), this.scale(done, ratioB));
    };
    /**
     * * 范围内的随机向量
     * 
     * @param {server.Vector3} start - 向量对象
     * 
     * @param {server.Vector3} done - 向量对象
     * 
     * @returns {server.Vector3} - 计算后的向量对象
     */
    static random(start: server.Vector3, done: server.Vector3): server.Vector3 {
        /**
         * * 获取两个向量范围
         */
        const range = new server.BlockVolume(start, done);
        /**
         * * 向量空间 的 最小值顶点
         */
        const min = range.getMin();
        /**
         * * 向量空间 的 最大值顶点
         */
        const max = range.getMax();
        // 随机生成一个向量
        return {
            x: Random({ min: min.x, max: max.x }),
            y: Random({ min: min.y, max: max.y }),
            z: Random({ min: min.z, max: max.z })
        }
    };
    /**
     * * 计算 向量空间 的 差向量 并 归一化
     * 
     * @param {server.Vector3} start - 向量对象
     * 
     * @param {server.Vector3} done - 向量对象
     * 
     * @returns {server.Vector3} - 计算后的向量对象
     */
    static difference(start: server.Vector3, done: server.Vector3): server.Vector3 {
        /**
         * * 计算 两个向量 的 基本向量
         */
        const direction = this.subtract(done, start);
        // 返回 归一化后 的 差向量
        return this.normalize(direction);
    };
    /** 
     * * 基于 实体旋转 获取 指向信息 的 3轴矢量
     * 
     * @param {server.Vector2} rotate - 实体旋转的 2轴矢量
     */
    static AngleToPlace(rotate: server.Vector2): server.Vector3 {
        /**
         * * 旋转角度(俯仰角)
         */
        const ry = -rotate.y * Math.PI / 180;
        /**
         * * 旋转角度(偏航角)
         */
        const rx = -rotate.x * Math.PI / 180;
        /**
         * * x 轴分量
         */
        const x = Math.sin(ry) * Math.cos(rx);
        /**
         * * Y 轴分量
         */
        const y = Math.sin(rx);
        /**
         * * Z 轴分量
         */
        const z = Math.cos(ry) * Math.cos(rx);
        // 返回指向的三维向量
        return { x, y, z };
    };
    /**
     * * 计算 目标方向相关 的 方向向量集
     *
     * @param {server.Vector3} front - 前方 方向向量
     * 
     * @returns {VECTOR_DIRECTIONS} - 包含计算出的方向向量的对象
     */
    static directions(front: server.Vector3): VECTOR_DIRECTIONS {
        /**
         * * 定义 常量 向量
         */
        const sample: server.Vector3 = this.CONSTANT_UP;
        /**
         * * 后方 方向向量
         */
        const back: server.Vector3 = this.normalize(this.scale(front, -1));
        /**
         * * 右方 方向向量
         */
        const right: server.Vector3 = this.normalize(this.cross(front, sample));
        /**
         * * 左方 方向向量
         */
        const left: server.Vector3 = this.normalize(this.scale(right, -1));
        /**
         * * 下方 方向向量
         */
        const down: server.Vector3 = this.normalize(this.cross(front, right));
        /**
         * * 上方 方向向量
         */
        const above: server.Vector3 = this.normalize(this.scale(down, -1));
        // 返回计算结果
        return { front, back, left, right, above, down };
    };
    /**
     * * 计算 目标方向相关 的 坐标偏移
     * 
     * @param {server.Vector3} source - 进行计算的源坐标
     * 
     * @param {server.Vector3} front - 前方向向量
     * 
     * @param {VECTOR_RELATIVE_OFFSET} offset - 偏移量
     * 
     * @returns {server.Vector3} - 计算后的坐标
     */
    static relativeOffset(source: server.Vector3, front: server.Vector3, offset: VECTOR_RELATIVE_OFFSET): server.Vector3 {
        /**
         * * 计算 方向向量集
         */
        const directions = this.directions(front);
        /**
         * * 计算 前方偏移量
         */
        const frontScale = this.scale(front, offset.front);
        /**
         * * 计算 右方偏移量
         */
        const rightScale = this.scale(directions.right, offset.right);
        /**
         * * 计算 上方偏移量
         */
        const upScale = this.scale(directions.above, offset.above);
        // 返回偏移量
        return this.add(source, this.add(frontScale, this.add(upScale, rightScale)));
    };
    /**
     * * 提前量计算
     * 
     * @param {server.Vector3} posA - 点 A 的位置
     * 
     * @param {server.Vector3} posB - 点 B 的位置
     * 
     * @param {number} speedA - A 发射的直线弹射物的速率
     * 
     * @param {server.Vector3} velB - B 的速度
     * 
     * @returns {server.Vector3} - A 发射的直线弹射物的速度
     */
    static calculateLeadVelocity(posA: server.Vector3, posB: server.Vector3, speedA: number, velB: server.Vector3): server.Vector3 {
        /**
         * * 计算 向量BA
         */
        const vecBA = this.subtract(posB, posA);
        /**
         * * 计算 向量BA的归一化向量
         */
        const normVecBA = this.normalize(vecBA);
        /**
         * * 计算 向量BA与速度B的点积
         */
        const compVbBA = this.dot(velB, normVecBA);
        /**
         * * 计算 向量BA与归一化B的垂直分量
         */
        const vbAlongBA = this.scale(normVecBA, compVbBA);
        /**
         * * 计算 向量BA与速度B的垂直分量
         */
        const perpCompVa = this.subtract(velB, vbAlongBA);
        /**
         * * 计算 向量BA与速度A的垂直分量
         */
        const magVaBA = Math.sqrt(speedA * speedA - this.dot(perpCompVa, perpCompVa));
        // 如果A的发射速度在BA方向上的分量为负数, 则返回速度B的垂直分量
        if (magVaBA <= 0) return perpCompVa;
        /**
         * * 计算 A 发射的直线弹射物的速度向量
         */
        const vaAlongBA = this.scale(normVecBA, -magVaBA);
        // 计算最终的速度向量（A的发射速度）
        return this.add(perpCompVa, vaAlongBA);
    };
    /**
     * * 获取区块坐标
     * 
     * @param {server.Vector3} vector - 计算前的原始坐标
     * 
     * @param {boolean} Yzero - 是否将 Y轴 的值设置为 0
     * 
     * @param {number} size - 区块大小
     * 
     * @returns {server.Vector3} - 计算后的区块坐标
     */
    static chunkLocation(vector: server.Vector3, Yzero: boolean = true, size: number = 16): server.Vector3 {
        /**
         * * 计算 Y轴 的值
         */
        const y = Yzero ? 0 : vector.y;
        // 返回计算结果
        return { x: Math.floor(vector.x / size) * size, y, z: Math.floor(vector.z / size) * size };
    };
    /**
     * 常量: 0.5 向量
     * 返回一个所有分量都为 0.5 的向量
     */
    static get CONSTANT_HALF(): server.Vector3 { return { x: 0.5, y: 0.5, z: 0.5 } };
    /**
     * 常量: 0 向量
     * 返回一个所有分量都为 0 的向量
     */
    static get CONSTANT_ZERO(): server.Vector3 { return { x: 0, y: 0, z: 0 } };
    /**
     * 常量: 向上单位向量
     * 返回一个y分量为 1, 其余分量为 0 的向上单位向量
     */
    static get CONSTANT_UP(): server.Vector3 { return { x: 0, y: 1, z: 0 } };
    /**
     * 常量: 向下单位向量
     * 返回一个y分量为 -1, 其余分量为 0 的向下单位向量
     */
    static get CONSTANT_DOWN(): server.Vector3 { return { x: 0, y: -1, z: 0 } };
    /**
     * 常量: 正一向量
     * 返回一个所有分量都是 1 的单位向量
     */
    static get CONSTANT_ONE(): server.Vector3 { return { x: 1, y: 1, z: 1 } };
    /**
     * 常量: 负一向量
     * 返回一个所有分量都是 -1 的单位向量
     */
    static get CONSTANT_LOSS_ONE(): server.Vector3 { return { x: -1, y: -1, z: -1 } };
    /**
     * 常量: 西方向单位向量
     * 返回一个x分量为 -1, 其余分量为 0 的向西方向单位向量
     */
    static get CONSTANT_WEST(): server.Vector3 { return { x: -1, y: 0, z: 0 } };
    /**
     * 常量: 东方向单位向量
     * 返回一个x分量为 1, 其余分量为 0 的向东方向单位向量
     */
    static get CONSTANT_EAST(): server.Vector3 { return { x: 1, y: 0, z: 0 } };
    /**
     * 常量: 北方向单位向量
     * 返回一个z分量为 1, 其余分量为 0 的向北方向单位向量
     */
    static get CONSTANT_SOUTH(): server.Vector3 { return { x: 0, y: 0, z: 1 } };
    /**
     * 常量: 南方向单位向量
     * 返回一个z分量为 -1, 其余分量为 0 的向南方向单位向量
     */
    static get CONSTANT_NORTH(): server.Vector3 { return { x: 0, y: 0, z: -1 } };
    /**
     * * 无效的构造函数
     */
    protected constructor() { };
};
/** 
 * * 在范围内寻找合适的落脚点
 * 
 * @param {data_format.LOCATION_AND_DIMENSION} source 带有位置与维度信息的实例
 * 
 * @param {number} range 最大检测范围
 * 
 * @param {number} height 最小检测高度
 *
 * @param {number} limit 最大检测高度
 */
function QueryFoothold(source: data_format.LOCATION_AND_DIMENSION, range: number, height: number, limit: number): server.Vector3 {
    /** 
     * * 定义 输出的 坐标
     */
    let output: server.Vector3 = Vector.CONSTANT_ZERO;
    /** 
     * * 设置最大循环次数 以避免无限循环
     */
    const maxRepeat: number = 1024;
    /** 
     * * 设置 循环 的 计数值
     */
    let alpha: number = 1;
    // 循环 1024 次
    while (alpha > 0 && alpha <= maxRepeat) {
        // 获取 随机值
        const random0 = Random({ max: 3, min: 0 }, true);
        const random1 = Random({ max: range, min: 16 }, true);
        const random2 = Random({ max: -16, min: -range }, true);
        // 修改 着陆点 坐标
        output =
        {
            x: source.location.x + (random0 === 0 || random0 === 2 ? random1 : random2),
            y: Random({ max: limit, min: height }, true),
            z: source.location.z + (random0 === 0 || random0 === 3 ? random1 : random2)
        }
        //判定 目标点附近 的 方块类型
        const getBlock0 = source.dimension.getBlock(output);
        const getBlock1 = source.dimension.getBlock(Vector.add(output, this.CONSTANT_UP));
        const getBlock2 = source.dimension.getBlock(Vector.add(output, { x: 0, y: -3, z: 0 }));
        const getBlock3 = source.dimension.getBlock(Vector.add(output, { x: 8, y: -2, z: 8 }));
        const getBlock4 = source.dimension.getBlock(Vector.add(output, { x: -8, y: -4, z: -8 }));
        //测试 目标阵列 是否 满足条件
        if (getBlock0?.isAir && getBlock1?.isAir && getBlock2 && getBlock3 && getBlock4) {
            //设置 测试点参数
            const test2 = getBlock2.isSolid;
            const test3 = getBlock3.isSolid;
            const test4 = getBlock4.isSolid;
            //确认 是否 满足条件
            if (test2 && test3 && test4) alpha = -1;
        }
        alpha++;
    }
    //达到最大循环次数 时 返回 起点 否则 返回 计算值
    return alpha == maxRepeat ? source.location : output;
};
/** 
 * * 在范围内寻找合适的实体落脚点
 * 
 * @param {server.Entity} source 带有位置与维度信息的实例
 * 
 * @param {number} scale 最大检测次数
 * 
 * @param {number} range 最大检测范围
 */
function QueryEntityFoothold(source: data_format.LOCATION_AND_DIMENSION, scale: number, range: number): server.Vector3 {
    /**
     * * 实体查询参数
     */
    const options: server.EntityQueryOptions = {
        excludeTypes: [...data_entity.area_legend.keys(), "minecraft:player"],
        location: source.location,
        maxDistance: range,
        closest: scale
    };
    /**
     * * 获取 实体列表
     */
    const entitys = source.dimension.getEntities(options);
    // 如果 方块列表 为空 则返回 起点
    if (entitys.length < 1) return Vector.add(source.location, { x: 0, y: 255, z: 0 });
    /**
     * * 获取 方块列表
     */
    const blocks = entitys.map(entity => entity.dimension.getBlock(entity.location));
    // 如果 方块列表 为空 则返回 起点
    if (entitys.length < 1) return Vector.add(source.location, { x: 0, y: 128, z: 0 });
    /**
     * * 获取 有效方块列表
     */
    const output = blocks.filter(
        block => {
            // 判断 方块是否有效
            if (!block) return false;
            /**
             * * 获取 上方的 方块
             */
            const above = block.above();
            /**
             * * 获取 下方的 方块
             */
            const below = block.below();
            /**
             * * 获取 东方的 方块
             */
            const east = below?.east();
            /**
             * * 获取 南方的 方块
             */
            const south = below?.south();
            // 判断 方块是否有效
            if (!above?.isAir && !above?.isLiquid) return false;
            if (below?.isAir || below?.isLiquid) return false;
            if (south?.isAir || south?.isLiquid) return false;
            if (east?.isAir || east?.isLiquid) return false;
            return true;
        }
    ) as server.Block[];
    // 排序 方块列表
    output.sort(
        (a, b) => {
            const distance_a = Vector.distance(source.location, a.location);
            const distance_b = Vector.distance(source.location, b.location);
            return distance_a - distance_b;
        }
    );
    // 如果 方块列表 为空 则返回 起点
    if (output.length < 1) return Vector.add(source.location, { x: 0, y: 64, z: 0 });
    else return output[0].location;
};
/** 
 * * 基于 数据范围 输出夹位值
 * 
 * @param {data_format.Vertex} input 包含数字范围的 Vertex 对象
 * 
 * @param {number} test 用于测试的数值
 * 
 * @returns {number} 输出的夹位值
 */
function Clamp(input: VERTEX, test: number): number {
    return Math.max(input.min, Math.min(input.max, test));
};
/**
 * * 生成 指定范围 内 的 随机值
 * 
 * @param {VERTEX} input 包含数字范围的 VERTEX 对象
 * 
 * @param {boolean} integer 是否生成整数, true 为生成整数, false 为生成浮点数
 * 
 * @returns {number} 输出 范围内 的 随机值
 */
function Random(input: VERTEX, integer?: boolean): number {
    if (integer == true) {
        // 输出 指定范围内 的 随机整数
        return Math.floor(Math.random() * (input.max - input.min + 1) + input.min);
    }
    else {
        // 输出 指定范围内 的 随机浮点数
        return Math.random() * (input.max - input.min) + input.min;
    }
};
/**
 * * 计算数组的中位数
 * 
 * @param {number[]} input - 求值的数组
 * 
 * @returns {number} - 中位数
 */
function median(input: number[]): number {
    /**
     * * 数组排序
     */
    const price = input.sort((a, b) => a - b);
    /**
     * * 中位数的索引值
     */
    const index = Math.floor(price.length / 2);
    // 判断数组长度是奇数还是偶数, 返回相应的中位数
    return price.length % 2 === 0
        ? (price[index - 1] + price[index]) / 2
        : price[index];
};
/**
 * * 计算数组的众数
 * 
 * @param {number[]} input - 求值的数组
 * 
 * @returns {number[]} - 众数
 */
function mode(input: number[]): number[] {
    /**
     * * 数值与其出现的频率
     */
    const frequency = new Map<number, number>();
    /**
     * * 众数
     */
    let mode: number[] = [];
    /**
     * * 最大频率
     */
    let maxFrequency = 0;
    // 遍历数组, 更新频率映射
    input.forEach(
        num => {
            if (frequency.has(num)) {
                frequency.set(num, frequency.get(num)! + 1);
            }
            else {
                frequency.set(num, 1);
            }
        }
    );
    // 遍历频率映射, 找到最大频率和对应的众数
    frequency.forEach(
        (frequency, num) => {
            if (frequency > maxFrequency) {
                maxFrequency = frequency;
                mode = [num];
            }
            else if (frequency === maxFrequency) {
                mode.push(num);
            }
        }
    );
    return mode;
};
/**
 * * 生成序列号
 *
 * @param {number|undefined} deplete - 序列号偏移量
 * 
 * @returns {number} - 生成的序列号
 */
function NumberID(deplete?: number): number {
    /**
     * * 序列号偏移量
     */
    const change = deplete ?? server.system.currentTick;
    // 输出
    return Number.MAX_SAFE_INTEGER - change;
};
/**
 * * 向量偏移接口
 */
interface VECTOR_RELATIVE_OFFSET {
    /**
     * * 前方 偏移量
     */
    front: number;
    /**
     * * 右方 偏移量
     */
    right: number;
    /**
     * * 上方 偏移量
     */
    above: number;
};
/**
 * * 向量方向接口
 */
interface VECTOR_DIRECTIONS {
    /**
     * * 右方 向量
     */
    right: server.Vector3;
    /**
     * * 后方 向量
     */
    back: server.Vector3;
    /**
     * * 左方 向量
     */
    left: server.Vector3;
    /**
     * * 前方 向量
     */
    front: server.Vector3;
    /**
     * * 上方 向量
     */
    above: server.Vector3;
    /**
     * * 下方 向量
     */
    down: server.Vector3
};
/**
 * * 矢量 字符串化 参数
 */
interface VECTOR_STRING_OPTIONS {
    /**
     * * 指定要保留的小数位数, 默认为" 2 "
     */
    decimals?: number;
    /**
     * * 指定分隔符, 默认为" , "
     */
    delimiter?: string
};
/**
 * * 矢量限制
 */
interface VECTOR_LIMITS {
    /**
     * * 最小值
     */
    min?: Partial<server.Vector3>;
    /**
     * * 最大值
     */
    max?: Partial<server.Vector3>;
};
/**
 * * 数组 特征信息 对象
 */
interface VERTEX {
    /**
     * * 获取数组的最大值
     */
    max: number;
    /**
     * * 获取数组的最小值
     */
    min: number;
    /**
     * * 获取数组的平均值
     */
    average?: number;
    /**
     * * 获取数组的中位值
     */
    median?: number;
    /**
     * * 获取数组的众数
     */
    mode?: number[];
};